#include <iostream>
#include <zlib/eventsystem/I_EventSystem.h>

using namespace std;

//EVENT_CODE是对全局的event起作用的,需要统一分配.
//因此需要在I_EVENT中统一分配如TEST_EVENT_CODE_NONE 资源.
//在每个功能所在文件中通过分配到的CODE_NONE进行偏移计算.
//每种类型的EVENT_CODE上限是100个.
#define TEST_EVENT_NONE 20000
#define TEST_EVENT_CONT  (TEST_EVENT_NONE + 1)
#define TEST_EVENT_DONE  (TEST_EVENT_NONE + 2)
#define TEST_EVENT_TEST  (TEST_EVENT_NONE + 3)

class TestCont : public Continuation
{
public:
	TestCont()
	{
		cout << "construct function" << endl;
		cout << "set TestCont callback is mainHandler" << endl;
		SET_HANDLER(&TestCont::mainHandler);
	}

	~TestCont()
	{
		cout << "destory function" << endl;
	}

	int mainHandler(int event, void *data)
	{
		if(event == TEST_EVENT_CONT)
		{
			cout << "CONT: again" << endl;
		}

		if(event == TEST_EVENT_DONE)
		{
			cout << "DONE: destory" << endl;
			Action *a = (Action *)data;
			cout << "cancle action" << endl;
			a->cancle_action();
			delete this;
		}

		if(event == TEST_EVENT_TEST)
		{
			cout << "CONT: test" << endl;
		}
	}
};

int main()
{
	TestCont *t = new TestCont;
	t->mutex = new_ProxyMutex();

	Action a;
	cout << "cancled:" << a.cancelled << " continuation:" << a.continuation << " mutex:" << a.mutex << endl;
	a = t;// operator=
	cout << "cancled:" << a.cancelled << " continuation:" << a.continuation << " mutex:" << a.mutex << endl;
	MUTEX_TRY_LOCK(l, a.mutex, new EThread(1));
	if(!l.is_locked())
	{
		cout << "lock faild, exit" << endl;
		return 1;
	}

	cout << "lock success, continue" << endl;
	if(a.cancelled)
	{
		cout << "the action is cancelled, exit" << endl;
		return 2;
	}

	cout << "the action is not cancelled" << endl;

	a.continuation->handleEvent(TEST_EVENT_CONT, NULL);
	if(a.cancelled)
	{
		cout << "the action is cancelled, exit" << endl;
		return 2;
	}
	
	a.continuation->handleEvent(TEST_EVENT_TEST, NULL);
	if(a.cancelled)
	{
		cout << "the action is cancelled, exit" << endl;
		return 2;
	}

	a.continuation->handleEvent(TEST_EVENT_DONE, &a);
	if(a.cancelled)
	{
		cout << "test event done : the action is cancled" << endl;
	}

	return 0;
}
